﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Gmmy.ApplicationExtension;
using Gmmy.Utility;
using Gmmy.Utility.Enums;
using Host.Dto;
using log4net;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Surging.Core.ProxyGenerator;
using Surging.Core.CPlatform.Ioc;
using Surging.Core.Caching;
using Surging.Core.CPlatform.Cache;
using Surging.Core.CPlatform.Routing;
namespace Host.Module
{
    [ModuleName("Auth")]
    public class AuthService : ProxyBaseService, IAuthService
    {
        private readonly IServiceProxyProvider _serviceProxyProvider;
        private readonly ILogger<AuthService> _logger;
        private readonly IBaseModule _baseModule;
        public AuthService(
            IServiceProxyProvider serviceProxyProvider,
            ILogger<AuthService> logger
            , IServiceRouteProvider serviceRouteProvider, IBaseModule baseModule
            ) :base(logger)
        {
            _serviceProxyProvider = serviceProxyProvider;
            _baseModule = baseModule;
            _logger = logger;
        }
        /// <summary>
        /// 登录认证
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CustomApiResult> Authentication(AuthenticationRequestData input)
        {
            return await Do(input, async result =>
             {
                 var proxyInput = new Dictionary<string, object> { { "input", JsonConvert.DeserializeObject(JsonConvert.SerializeObject(input)) } };
                 var proxyResult =
                     await _serviceProxyProvider.Invoke<CustomApiResult>(proxyInput, "api/User/Login", "User");
                 if (proxyResult.code == CustomApiResultCode.Succ)
                 {
                     _baseModule.CreateCacheToken(proxyResult.data, result);
                 }
                 else
                 {
                     throw new CustomException(proxyResult.message);
                 }
             });
        }

        /// <summary>
        /// 获取登陆者信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>

        public async Task<CustomApiResult> Info(AuthToken input)
        {
            return await Do(input, async result =>
            {
                var check = await _baseModule.CheckTokenCache(input.Token);
                if (check.isSuccess)
                {
                    result.data = await _baseModule.GetUserRoleCache(check.jwtToken.ToList());
                }
                else
                {
                    throw new CustomException(CustomApiResultCode.AuthenticationInvalid, "");
                }
            });
        }


        /// <summary>
        /// 更新用户token
        /// </summary>
        /// <param name="input"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task<CustomApiResult> UpdateToken(UpdateTokenDto input, string token)
        {
            return await Do(input, async result =>
            {
                await _baseModule.RemoveTokenCache(token);
                await _baseModule.CreateCacheToken(input, result);
            });
        }

        /// <summary>
        /// 网关授权检测
        /// </summary>
        /// <param name="input"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public async Task<CustomApiResult> AuthorizationCheck(UserCheckDto input)
        {
            return await Do(input, async result =>
            {
                var check = await _baseModule.CheckTokenCache(input.Token);
                if (check.isSuccess)
                {
                    var token = check.jwtToken.ToList();
                    var moduleData = (await _baseModule.GetAllModuleAddress(token)).Select(x => x.ToLower());
                    //若当前路由在路由集合中
                    if (moduleData.Contains(input.Path.ToLower()))
                    {
                        //若当前路由在用户权限中
                        if ((await _baseModule.GetUserRoleCache(token)).Actions.Select(x => x.ActionAddress.ToLower())
                            .Contains(input.Path.ToLower()))
                        {
                            result.data = Encoding.UTF8.GetString(Convert.FromBase64String(token[1]));
                        }
                        else
                        {
                            throw new CustomException(CustomApiResultCode.AuthorizationInvalid, "");
                        }
                    }
                    else
                    {
                        //路由没在集合中则通过
                        result.data = Encoding.UTF8.GetString(Convert.FromBase64String(token[1]));
                    }
                }
                else
                {
                    throw new CustomException(CustomApiResultCode.AuthenticationInvalid, "");
                }
            });
        }

        /// <summary>
        /// 用户登出
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<CustomApiResult> Logout(AuthToken input)
        {
            return await Do(input, async result =>
            {
                await _baseModule.RemoveTokenCache(input.Token);
            });
        }
    }
}
